home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / MLT_TASK / PIBMDOS / PIBMDOS.PAS < prev    next >
Pascal/Delphi Source File  |  1988-06-05  |  23KB  |  479 lines

  1. (*--------------------------------------------------------------------------*)
  2. (*             PIBMDOS.PAS --- Multitasker interface routines               *)
  3. (*--------------------------------------------------------------------------*)
  4. (*                                                                          *)
  5. (*  Author:  Philip R. Burns                                                *)
  6. (*                                                                          *)
  7. (*  Date:    Version 1.0: January, 1986.   DoubleDos support.               *)
  8. (*           Version 2.0: April, 1986.     Add DesqView support.            *)
  9. (*           Version 3.0: July, 1986.      Add TopView/Windows support.     *)
  10. (*           Version 3.1: September, 1986. Update for TaskView support.     *)
  11. (*           Version 3.2: December, 1986.  Distinguish TaskView/DesqView.   *)
  12. (*           Version 4.0: January, 1988.   Fix bogus TopView update, add    *)
  13. (*                                         check for Novell to stop lockup, *)
  14. (*                                         convert to TP4.                  *)
  15. (*                                                                          *)
  16. (*  Systems: MS DOS or PC DOS with DoubleDos/DesqView/TopView/Windows       *)
  17. (*           installed.                                                     *)
  18. (*                                                                          *)
  19. (*  History: These routines provide a simple interface for PibTerm          *)
  20. (*           with SoftLogic's DoubleDos multitasking executive,             *)
  21. (*           Quarterdeck's DesqView multitasker, IBM's TopView,             *)
  22. (*           MicroSoft's Windows, and Sunny Hill's TaskView/OmniView.       *)
  23. (*           (Windows is handled as a Topview-emulating product.  This is   *)
  24. (*           also true for TaskView, DesqView, and OmniView, but those      *)
  25. (*           programs do not require the explicit screen updates TopView    *)
  26. (*           requires.                                                      *)
  27. (*                                                                          *)
  28. (*           If you have another multitasker, you should be able to         *)
  29. (*           replace these routines fairly easily with similar-acting       *)
  30. (*           ones for your multitasker.  Use the global types defined       *)
  31. (*           for MultiTasker and MultiTaskerType.                           *)
  32. (*                                                                          *)
  33. (*           Note also that the routine Get_Screen_Address in Pibscren.pas  *)
  34. (*           needs to know about multitaskers.                              *)
  35. (*                                                                          *)
  36. (*           With DoubleDos, it is necessary to reobtain the display buffer *)
  37. (*           address every time the screen memory is written to.  With      *)
  38. (*           DesqView, this is unnecessary.  With TopView and Windows,      *)
  39. (*           it is necessary to inform them that the screen has changed.    *)
  40. (*           TaskView works like DesqView.                                  *)
  41. (*                                                                          *)
  42. (*--------------------------------------------------------------------------*)
  43. (*                                                                          *)
  44. (*           Please leave messages on Gene Plantz's BBS (312) 882 4145      *)
  45. (*           or Ron Fox's BBS (312) 940 6496.                               *)
  46. (*                                                                          *)
  47. (*--------------------------------------------------------------------------*)
  48.  
  49. (*--------------------------------------------------------------------------*)
  50. (*           IsNovellActive  --- Checks if Novell network is active         *)
  51. (*--------------------------------------------------------------------------*)
  52.  
  53. FUNCTION IsNovellActive : BOOLEAN;
  54.  
  55. (*--------------------------------------------------------------------------*)
  56. (*                                                                          *)
  57. (*    Function: IsNovellActive                                              *)
  58. (*                                                                          *)
  59. (*    Purpose:  Checks if Novell network active                             *)
  60. (*                                                                          *)
  61. (*    Calling Sequence:                                                     *)
  62. (*                                                                          *)
  63. (*       Novell_On := IsNovellActive : BOOLEAN;                             *)
  64. (*                                                                          *)
  65. (*          Novell_On --- TRUE if Novell network is active.                 *)
  66. (*                                                                          *)
  67. (*    Calls:  MsDos                                                         *)
  68. (*                                                                          *)
  69. (*--------------------------------------------------------------------------*)
  70.  
  71. VAR
  72.    Regs : Registers;
  73.  
  74. BEGIN (* IsNovellActive *)
  75.  
  76.    Regs.CX := 0;
  77.    Regs.AL := 0;
  78.                                    (* Request workstation ID.          *)
  79.                                    (* This should be ignored if Novell *)
  80.                                    (* network software isn't active.   *)
  81.    Regs.AH := $DC;
  82.  
  83.    MsDos( Regs );
  84.                                    (* If we got back a non-zero station *)
  85.                                    (* ID, then Novell must be loaded.   *)
  86.  
  87.    IsNovellActive := ( Regs.AL <> 0 );
  88.  
  89. END   (* IsNovellActive *);
  90.  
  91. (*--------------------------------------------------------------------------*)
  92. (*           IsTimeSharingActive --- Checks if multitasker is active        *)
  93. (*--------------------------------------------------------------------------*)
  94.  
  95. FUNCTION IsTimeSharingActive : BOOLEAN;
  96.  
  97. (*--------------------------------------------------------------------------*)
  98. (*                                                                          *)
  99. (*    Function: IsTimeSharingActive                                         *)
  100. (*                                                                          *)
  101. (*    Purpose:  Checks if multitasker is active                             *)
  102. (*                                                                          *)
  103. (*    Calling Sequence:                                                     *)
  104. (*                                                                          *)
  105. (*       Ts_On := IsTimeSharingActive : BOOLEAN;                            *)
  106. (*                                                                          *)
  107. (*          Ts_On --- TRUE if multitasker is active.                        *)
  108. (*                                                                          *)
  109. (*    Calls:  MsDos                                                         *)
  110. (*                                                                          *)
  111. (*--------------------------------------------------------------------------*)
  112.  
  113. VAR
  114.    Regs : Registers;
  115.  
  116. (*--------------------------------------------------------------------------*)
  117.  
  118. FUNCTION Get_TopView_Screen_Address : BOOLEAN;
  119.  
  120. VAR
  121.    SegS : INTEGER;
  122.    SegO : INTEGER;
  123.  
  124. BEGIN (* Get_TopView_Screen_Address *)
  125.  
  126.    Regs.Di := 0;
  127.    Regs.Ax := $FE00;
  128.    Regs.Es := SEG( Virtual_Screen^ );
  129.  
  130.    SegO    := 0;
  131.    SegS    := Regs.Es;
  132.  
  133.    INTR( $10 , Regs );
  134.  
  135.    Virtual_Screen := PTR( Regs.Es , Regs.Di );
  136.  
  137.    Get_TopView_Screen_Address := ( ( Regs.Es <> SegS ) OR ( Regs.Di <> SegO ) );
  138.  
  139. END   (* Get_TopView_Screen_Address *);
  140.  
  141. (*--------------------------------------------------------------------------*)
  142.  
  143. BEGIN (* IsTimeSharingActive *)
  144.                                    (* Assume timesharing not active *)
  145.    IsTimeSharingActive := FALSE;
  146.    MultiTasker         := MultiTasker_None;
  147.  
  148.                                    (* Determine if color or mono screen *)
  149.    Regs.Ax := 15 SHL 8;
  150.    INTR( $10 , Regs );
  151.                                    (* Get initial screen address    *)
  152.    IF ( Regs.AL <> 7 ) THEN
  153.       Virtual_Screen := PTR( Color_Screen_Address , 0 )
  154.    ELSE
  155.       Virtual_Screen := PTR( Mono_Screen_Address  , 0 );
  156.  
  157.                                    (* If Novell network not active, *)
  158.                                    (* check if DoubleDos is active. *)
  159.    IF ( NOT IsNovellActive ) THEN
  160.       BEGIN
  161.                                    (* If DDos is active, $E4 should *)
  162.                                    (* return a non-zero value in Al *)
  163.          Regs.Ax := $E400;
  164.  
  165.          MsDos( Regs );
  166.  
  167.          IF ( Regs.Al <> 0 ) THEN
  168.             BEGIN
  169.                IsTimeSharingActive := TRUE;
  170.                MultiTasker         := DoubleDos;
  171.                EXIT;
  172.             END;
  173.  
  174.       END;
  175.                                    (* See if DesqView is active.        *)
  176.                                    (* We do a time/date call with       *)
  177.                                    (* DESQ as date.  If DesqView is     *)
  178.                                    (* active, this will be accepted.    *)
  179.                                    (* If not, it returns as invalid.    *)
  180.                                    (* While we're at it, get the        *)
  181.                                    (* display buffer address, which     *)
  182.                                    (* never changes.                    *)
  183.                                    (*                                   *)
  184.                                    (* NOTE:  Newer versions of TaskView *)
  185.                                    (*        also accept this DesqView  *)
  186.                                    (*        call, so we must check the *)
  187.                                    (*        TopView number to differ-  *)
  188.                                    (*        entiate them.              *)
  189.    Regs.Ax := $2B01;
  190.    Regs.Cx := $4445;  (*'DE'*)
  191.    Regs.Dx := $5351;  (*'SQ'*)
  192.    MsDos( Regs );
  193.  
  194.    IF ( Regs.Al <> $FF ) THEN
  195.       IF Get_TopView_Screen_Address THEN
  196.          BEGIN
  197.  
  198.             IsTimeSharingActive := TRUE;
  199.  
  200.                                    (* Distinguish TaskView from TopView *)
  201.             Regs.Ax := $1022;
  202.             Regs.Bx := 0;
  203.             INTR( $15 , Regs );
  204.  
  205.             IF ( Regs.Bx = 1 ) THEN
  206.                MultiTasker         := TaskView
  207.             ELSE
  208.                MultiTasker         := DesqView;
  209.  
  210.             EXIT;
  211.  
  212.          END;
  213.                                    (* Check for TaskView or TopView.  We do   *)
  214.                                    (* a request for a TopView version number. *)
  215.                                    (* If BX comes back $0001, this must be    *)
  216.                                    (* TaskView.  Anything non-zero indicates  *)
  217.                                    (* TopView or a compatible program.        *)
  218.                                    (* Note:  This catches older TaskView      *)
  219.                                    (*        versions which don't understand  *)
  220.                                    (*        the DesqView call.               *)
  221.    Regs.Ax := $1022;
  222.    Regs.Bx := 0;
  223.    INTR( $15 , Regs );
  224.  
  225.    IF ( Regs.Bx <> 0 ) THEN
  226.       BEGIN
  227.  
  228.          IF ( Regs.Bx = 1 ) THEN
  229.             MultiTasker         := TaskView
  230.          ELSE
  231.             MultiTasker         := TopView;
  232.  
  233.          IF ( NOT Get_TopView_Screen_Address ) THEN
  234.             MultiTasker := Multitasker_None
  235.          ELSE
  236.             IsTimeSharingActive := TRUE;
  237.  
  238.       END;
  239.  
  240. END   (* IsTimeSharingActive *);
  241.  
  242. (*--------------------------------------------------------------------------*)
  243. (*    TurnOnTimeSharing --- allow timesharing to proceed                    *)
  244. (*--------------------------------------------------------------------------*)
  245.  
  246. PROCEDURE TurnOnTimeSharing;
  247.  
  248. (*--------------------------------------------------------------------------*)
  249. (*                                                                          *)
  250. (*    Procedure:  TurnOnTimeSharing;                                        *)
  251. (*                                                                          *)
  252. (*    Purpose:    Activates timesharing                                     *)
  253. (*                                                                          *)
  254. (*    Calling Sequence:                                                     *)
  255. (*                                                                          *)
  256. (*       TurnOnTimeSharing;                                                 *)
  257. (*                                                                          *)
  258. (*    Calls:  MsDos                                                         *)
  259. (*                                                                          *)
  260. (*--------------------------------------------------------------------------*)
  261.  
  262. VAR
  263.    Regs : Registers;
  264.  
  265. BEGIN (* TurnOnTimeSharing *)
  266.  
  267.    CASE MultiTasker OF
  268.                                    (* If DDos is active, $EB turns  *)
  269.                                    (* on timesharing                *)
  270.       DoubleDos:   BEGIN
  271.                       Regs.Ax := $EB00;
  272.                       MsDos( Regs );
  273.                    END;
  274.  
  275.                                    (* Int 15H for TopView family products *)
  276.       DesqView,
  277.       TopView,
  278.       MSWindows,
  279.       TaskView:    BEGIN
  280.                       Regs.Ax := $101C;
  281.                       INTR( $15 , Regs );
  282.                    END;
  283.  
  284.       ELSE;
  285.  
  286.    END (* CASE *);
  287.  
  288. END   (* TurnOnTimeSharing *);
  289.  
  290. (*--------------------------------------------------------------------------*)
  291. (*        TurnOffTimeSharing --- suspend timesharing under DoubleDos        *)
  292. (*--------------------------------------------------------------------------*)
  293.  
  294. PROCEDURE TurnOffTimeSharing;
  295.  
  296. (*--------------------------------------------------------------------------*)
  297. (*                                                                          *)
  298. (*    Procedure:  TurnOffTimeSharing;                                       *)
  299. (*                                                                          *)
  300. (*    Purpose:    Suspends timesharing                                      *)
  301. (*                                                                          *)
  302. (*    Calling Sequence:                                                     *)
  303. (*                                                                          *)
  304. (*       TurnOffTimeSharing;                                                *)
  305. (*                                                                          *)
  306. (*    Calls:  MsDos                                                         *)
  307. (*                                                                          *)
  308. (*--------------------------------------------------------------------------*)
  309.  
  310. VAR
  311.    Regs : Registers;
  312.  
  313. BEGIN (* TurnOffTimeSharing *)
  314.  
  315.    CASE MultiTasker OF
  316.                                    (* If DDos is active, $EA suspends *)
  317.                                    (* timesharing                     *)
  318.       DoubleDos:   BEGIN
  319.                       Regs.Ax := $EA00;
  320.                       MsDos( Regs );
  321.                    END;
  322.                                    (* Int 15H for TopView family products *)
  323.       DesqView,
  324.       TopView,
  325.       MSWindows,
  326.       TaskView:    BEGIN
  327.                       Regs.Ax := $101B;
  328.                       INTR( $15 , Regs );
  329.                    END;
  330.  
  331.      ELSE;
  332.  
  333.    END (* CASE *);
  334.  
  335. END   (* TurnOffTimeSharing *);
  336.  
  337. (*--------------------------------------------------------------------------*)
  338. (*            GiveUpTime --- gives away time slices to other task           *)
  339. (*--------------------------------------------------------------------------*)
  340.  
  341. PROCEDURE GiveUpTime( NSlices : INTEGER );
  342.  
  343. (*--------------------------------------------------------------------------*)
  344. (*                                                                          *)
  345. (*    Procedure:  GiveUpTime;                                               *)
  346. (*                                                                          *)
  347. (*    Purpose:    Gives away time slices to other tasks                     *)
  348. (*                                                                          *)
  349. (*    Calling Sequence:                                                     *)
  350. (*                                                                          *)
  351. (*       GiveUpTime( NSlices :  INTEGER );                                  *)
  352. (*                                                                          *)
  353. (*          NSlices --- # of slices (55 ms) to give away, if DoubleDos.     *)
  354. (*                                                                          *)
  355. (*    Calls:  MsDos                                                         *)
  356. (*                                                                          *)
  357. (*--------------------------------------------------------------------------*)
  358.  
  359. VAR
  360.    Regs : Registers;
  361.  
  362. BEGIN (* GiveUpTime *)
  363.  
  364.    IF ( TimeSharingActive AND ( NSlices > 0 ) ) THEN
  365.       CASE MultiTasker OF
  366.                                    (* Function EE gives time to other part. *)
  367.          DoubleDos:   BEGIN
  368.                          Regs.Ah := $EE;
  369.                          Regs.Al := NSlices;
  370.                          MsDos( Regs );
  371.                       END;
  372.  
  373.          DesqView,
  374.          TopView,
  375.          MSWindows,
  376.          TaskView:    BEGIN
  377.                          INLINE(
  378.                                  $B8/$00/$10 { MOV     AX,$1000 ;Give up time}
  379.                                  /$CD/$15    { INT     $15}
  380.                                );
  381.                       END;
  382.  
  383.          ELSE;
  384.  
  385.       END;
  386.  
  387. END   (* GiveUpTime *);
  388.  
  389. (*--------------------------------------------------------------------------*)
  390. (*    Sync_Screen --- Synchronizes multitasker screen with hardware screen  *)
  391. (*--------------------------------------------------------------------------*)
  392.  
  393. PROCEDURE Sync_Screen( S_Pos: INTEGER; NChars : INTEGER );
  394.  
  395. (*--------------------------------------------------------------------------*)
  396. (*                                                                          *)
  397. (*    Procedure:  Sync_Screen;                                              *)
  398. (*                                                                          *)
  399. (*    Purpose:    Synchronizes multitasker and hardware screens             *)
  400. (*                                                                          *)
  401. (*    Calling Sequence:                                                     *)
  402. (*                                                                          *)
  403. (*       Sync_Screen( S_Pos : INTEGER; NChars: INTEGER );                   *)
  404. (*                                                                          *)
  405. (*    Calls:  INTR                                                          *)
  406. (*                                                                          *)
  407. (*    Remarks:                                                              *)
  408. (*                                                                          *)
  409. (*       This facility is required by the TopView-family products.          *)
  410. (*                                                                          *)
  411. (*--------------------------------------------------------------------------*)
  412.  
  413. BEGIN (* Sync_Screen *)
  414.  
  415.    IF ( NChars > 0 ) THEN
  416.       IF Write_Screen_Memory THEN
  417.          IF ( MultiTasker = TopView ) THEN
  418.             BEGIN
  419.  
  420. INLINE(
  421.   $55/                      {         PUSH    BP                      ;Save BP in case of clobber}
  422.   $C4/$3E/>VIRTUAL_SCREEN / {         LES     DI,[>Virtual_Screen]    ;Pick up screen address}
  423.   $8B/$8E/>NCHARS/          {         MOV     CX,[BP+>NChars]         ;Get update length in bytes}
  424.   $8B/$86/>S_POS/           {         MOV     AX,[BP+>S_Pos]          ;Get offset of area to update}
  425.   $01/$F8/                  {         ADD     AX,DI                   ;Add to offset of screen memory}
  426.   $89/$C7/                  {         MOV     DI,AX                   ;Starting address of update}
  427.   $B4/$FF/                  {         MOV     AH,$FF                  ;TopView synchronize screen}
  428.   $CD/$10/                  {         INT     $10                     ;Video interrupt}
  429.   $5D);                     {         POP     BP                      ;Restore BP}
  430.  
  431.             END;
  432.  
  433. END   (* Sync_Screen *);
  434.  
  435. (*--------------------------------------------------------------------------*)
  436. (* Sync_Entire_Screen --- Synchronizes multitasker screen with hardware     *)
  437. (*--------------------------------------------------------------------------*)
  438.  
  439. PROCEDURE Sync_Entire_Screen;
  440.  
  441. (*--------------------------------------------------------------------------*)
  442. (*                                                                          *)
  443. (*    Procedure:  Sync_Entire_Screen;                                       *)
  444. (*                                                                          *)
  445. (*    Purpose:    Synchronizes multitasker and hardware screens             *)
  446. (*                                                                          *)
  447. (*    Calling Sequence:                                                     *)
  448. (*                                                                          *)
  449. (*       Sync_Entire_Screen;                                                *)
  450. (*                                                                          *)
  451. (*    Calls:  INTR                                                          *)
  452. (*                                                                          *)
  453. (*    Remarks:                                                              *)
  454. (*                                                                          *)
  455. (*       This facility is used by the TopView-family products when the      *)
  456. (*       entire screen has been updated.                                    *)
  457. (*                                                                          *)
  458. (*--------------------------------------------------------------------------*)
  459.  
  460. BEGIN (* Sync_Entire_Screen *)
  461.  
  462.    IF Write_Screen_Memory THEN
  463.       IF ( MultiTasker  = TopView ) THEN
  464.          BEGIN
  465.  
  466.             INLINE(
  467.   $55                       { PUSH    BP                    ;Save BP in case of clobber}
  468.   /$C4/$3E/>VIRTUAL_SCREEN  { LES     DI,[>Virtual_Screen]  ;Pick up screen address}
  469.   /$8B/$0E/>SCREEN_LENGTH   { MOV     CX,[>Screen_Length]   ;Get update length in bytes}
  470.   /$D1/$E9                  { SHR     CX,1                  ;Update length in words}
  471.   /$B4/$FF                  { MOV     AH,$FF                ;TopView synchronize screen}
  472.   /$CD/$10                  { INT     $10                   ;Video interrupt}
  473.   /$5D                      { POP     BP                    ;Restore BP}
  474.                   );
  475.  
  476.          END;
  477.  
  478. END   (* Sync_Entire_Screen *);
  479.